package com.bw.net

import com.bw.common.Constant
import com.bw.common.sp.SPPropDelegate
import com.bw.common.sp.SPUtils
import com.bw.net.api.TokenApi
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

class RetrofitFactory {
    /**
     * 使用属性委托间接存储到SP
     */
    private var token:String by SPPropDelegate("token","",false)

    companion object{
        val retrofitInseance:RetrofitFactory by lazy(LazyThreadSafetyMode.SYNCHRONIZED){
            RetrofitFactory()
        }
    }
    val retrofit:Retrofit
    init {
        retrofit = Retrofit.Builder()
            .baseUrl(BuildConfig.BASEURL)
            .client(createOkHttpClient())
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//            .addCallAdapterFactory(Corout)
            .build()
    }
    /**
     * 设置自定义的OkHttpClient
     */
    private fun createOkHttpClient():OkHttpClient{
        return OkHttpClient.Builder()
            .readTimeout(Constant.TIMEOUT,TimeUnit.SECONDS)
            .writeTimeout(Constant.TIMEOUT,TimeUnit.SECONDS)
            .connectTimeout(Constant.TIMEOUT,TimeUnit.SECONDS)
            .addNetworkInterceptor(createLogInterceptor())
            .addInterceptor(createTokenInterceptor())
            .build()
    }
    /**
     * 创建处理Token的自定义拦截器
     */
    private fun createTokenInterceptor(): Interceptor {
        val  interceptor = Interceptor {
            val request = it.request()
            var response:Response?=null

/*            response=it.proceed(request)
            if (response.code()==401){
                //获取token
                val tokenApi:TokenApi=create(TokenApi::class.java)
                val token = tokenApi.getToken("password", Constant.AUTHCODE, "")
                val result = token!!.execute()
                //拿到的token
                val accessToken = result.body()!!.access_token
                //设置到请求头
                val newRequest = request.newBuilder()
                    .addHeader("Authorization", "bearer $accessToken")
                    .build()
                it.proceed(newRequest)
            }else{
                response
            }*/



            /**
             * 先从SP中获取已存在的Token
             * 存在：直接加到请求头中
             * 不存在：从后台获取token然后添加到请求头 缓存到SP中
             */
            if (token.isNotBlank()){
                println("----tokenSP:OK")
                response = doRequest(request,it)
            }else{
                println("----tokenSP:NO")
                response = it.proceed(request)
            }
           /*
           1.没有token  2.token过期
           */
            if (response!!.code()==401){

                requestToken()
                doRequest(request,it)

            }else{
                println("----response:200  token:$token")
                response
            }
        }
        return interceptor
    }
    private fun requestToken(){
        //获取token
        val tokenApi:TokenApi = create(TokenApi::class.java)
        val gtoken = tokenApi.getToken("password",Constant.AUTHCODE,"")
        //执行token
        val result = gtoken!!.execute()
        //拿到的token
        val accessToken = result.body()!!.access_token
        println("----获取token：$accessToken")
        /**
         * 将从服务器获取到的Token存入到SP中
         */
        token = accessToken
        println("----获取tokenSP：$token")
    }
    /**
     * 设置请求头并执行
     */
    private fun setRequestHeade(request: Request,chain:Interceptor.Chain):Request{
        println("----response:401  token:$token")
        return request.newBuilder()
            .addHeader("Authorization","bearer $token")
            .build()
    }
    /**
     * 获取Token然后设置到请求头
     */
    private fun doRequest(request: Request,chain:Interceptor.Chain):Response{
        return chain.proceed(setRequestHeade(request,chain))
    }
    /**
     * 创建日志拦截器
     */
    private fun createLogInterceptor(): Interceptor {
        val loginterceptor = HttpLoggingInterceptor()
        loginterceptor.level = HttpLoggingInterceptor.Level.BODY
        return loginterceptor
    }

    fun <T> create(service:Class<T>):T{
        return retrofit.create(service)
    }
}